//
//  Application.swift
//  SwiftHub
//
//  Created by Khoren Markosyan on 1/5/18.
//  Copyright © 2018 Khoren Markosyan. All rights reserved.
//

import UIKit

final class Application: NSObject {
    // MARK: - Singleton
    static let shared = Application()

    var window: UIWindow?

    var provider: SwiftHubAPI?
    let authManager: AuthManager
    let navigator: Navigator

    private override init() {
        authManager = AuthManager.shared
        navigator = Navigator.default
        super.init()
        updateProvider()
        
    }


    private func updateProvider() {
        let staging = Configs.Network.useStaging
        let githubProvider = staging ? GithubNetworking.stubbingNetworking(): GithubNetworking.defaultNetworking()
        let trendingGithubProvider = staging ? TrendingGithubNetworking.stubbingNetworking(): TrendingGithubNetworking.defaultNetworking()
        let codetabsProvider = staging ? CodetabsNetworking.stubbingNetworking(): CodetabsNetworking.defaultNetworking()
        let restApi = RestApi(githubProvider: githubProvider, trendingGithubProvider: trendingGithubProvider, codetabsProvider: codetabsProvider)
        provider = restApi

        if let token = authManager.token, Configs.Network.useStaging == false {
            switch token.type() {
            case .oAuth(let token), .personal(let token):
                provider = GraphApi(restApi: restApi, token: token)
            default: break
            }
        }
    }

    func presentInitialScreen(in window: UIWindow?) {
        updateProvider()
        guard let window = window, let provider = provider else { return }
        self.window = window

//        presentTestScreen(in: window)
//        return
//        #<总结>: 在主线程延迟0.5秒后异步执行闭包。
//
//        #<分析>:
//        1. `DispatchQueue.main`: 表示要在主线程上执行操作。
//        2. `asyncAfter`: 是`DispatchQueue`的一个方法，用于在指定延迟后异步执行闭包。
//        3. `deadline: .now() + 0.5`: 设置延迟时间，这里表示从当前时间`.now()`开始，延迟0.5秒。
//        4. 闭包`{ [weak self] in ... }`: 用于封装要延迟执行的代码。其中`[weak self]`是为了避免闭包内对`self`的强引用，防止循环引用导致内存泄漏。
//        5. 延迟执行是为了让应用界面有时间响应其他事件，或者等待某个操作完成后再执行某些UI更新操作，确保线程安全。
//        6. 使用`DispatchQueue`的`asyncAfter`方法可以避免阻塞主线程，提高应用的响应性。
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
//        可选链: if let user = User.currentUser(), let login = user.login这两部分构成了一个可选链。如果User.currentUser()返回nil，则整个if let语句块内的代码不会被执行，因为user不会被成功解包。同样地，如果user.login返回nil，则同样不会执行if let语句块内的代码。
            if let user = User.currentUser(), let login = user.login {
                analytics.identify(userId: login)
                analytics.set(.name(value: user.name ?? ""))
                analytics.set(.email(value: user.email ?? ""))
            }
//            #<总结>: 检查认证管理器中的token是否有效。
//
//            #<分析>:
//            1. **可选链(Optional Chaining)**：`self?.authManager.token?.isValid` 使用了可选链，这意味着如果`self`、`authManager`或`token`中的任何一个为`nil`，那么整个表达式就会立即返回`nil`，而不会尝试访问后续的`isValid`属性。
//            2. **空合并运算符(Nil Coalescing Operator)**：`??` 是一个空合并运算符，用于为可选值提供一个默认值。如果`self?.authManager.token?.isValid`的值为`nil`（也就是说，前面的链式调用中的任何一个为`nil`或`isValid`为`false`），则整个表达式的结果为`false`。
//            3. **代码优化**：代码已经非常简洁，没有冗余的部分。它使用了Swift的现代特性（如可选链和空合并运算符）来减少代码量和提高可读性。
//            4. **安全性**：通过检查`self`、`authManager`和`token`的可选性，代码避免了在`nil`值上调用方法或访问属性的风险，从而提高了安全性。

            let authorized = self?.authManager.token?.isValid ?? false
            let viewModel = HomeTabBarViewModel(authorized: authorized, provider: provider)
            self?.navigator.show(segue: .tabs(viewModel: viewModel), sender: nil, transition: .root(in: window))
        }
    }

    func presentTestScreen(in window: UIWindow?) {
        guard let window = window, let provider = provider else { return }
        let viewModel = UserViewModel(user: User(), provider: provider)
        navigator.show(segue: .userDetails(viewModel: viewModel), sender: nil, transition: .root(in: window))
    }
}
